package com.xiongkw.lockutil;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;

@Slf4j
public class DistributeLock {
    public static int defaultLockSeconds = 30;
    private static final String LOCK_SUCCESS = "OK";
    private static final Integer RELEASE_SUCCESS = 1;
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "EX";
    private static final ThreadLocal<String> lockAuthKey = new ThreadLocal<String>();

    public static boolean lock(Jedis jedis, DistributeLockPrefixEnum keyPrefix, String dataId) {
       return DistributeLock.lock(jedis,keyPrefix,dataId,defaultLockSeconds);
    }

    public static boolean lock(Jedis jedis, DistributeLockPrefixEnum keyPrefix, String dataId, int expireSeconds) {
        if(jedis == null || keyPrefix == null || dataId == null || expireSeconds == 0){
            throw new IllegalArgumentException();
        }
        String lockKey = keyPrefix.name()+dataId;
        String result = jedis.set(lockKey, dataId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireSeconds);

        return LOCK_SUCCESS.equalsIgnoreCase(result);
    }

    public static boolean unlock(Jedis redisClient, DistributeLockPrefixEnum keyPrefix, String dataId){
        if(redisClient == null || keyPrefix == null || dataId == null){
            throw new IllegalArgumentException();
        }
        String key = keyPrefix.name()+dataId;
        String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        Object eval = redisClient.eval(script, Lists.newArrayList(key), Lists.newArrayList(dataId));
        return Objects.equal(RELEASE_SUCCESS,eval);
    }
}
